package com.avic.modules.equipment.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONException;
import com.avic.common.service.impl.BaseServiceImpl;
import com.avic.common.utils.QueryHelpPlus;
import com.avic.dozer.service.IGenerator;
import com.avic.exception.BadRequestException;
import com.avic.modules.equipment.domain.Equipment;
import com.avic.modules.equipment.domain.EquipmentMaintain;
import com.avic.modules.equipment.domain.EquipmentRepair;
import com.avic.modules.equipment.domain.vo.Accept;
import com.avic.modules.equipment.domain.vo.RepairVo;
import com.avic.modules.equipment.service.EquipmentRepairService;
import com.avic.modules.equipment.service.dto.EquipmentRepairDto;
import com.avic.modules.equipment.service.dto.EquipmentRepairQueryCriteria;
import com.avic.modules.equipment.service.mapper.EquipmentMapper;
import com.avic.modules.equipment.service.mapper.EquipmentRepairMapper;
import com.avic.modules.log.domain.vo.LogEnumeration;
import com.avic.modules.log.domain.vo.LogVo;
import com.avic.modules.log.service.LogsService;
import com.avic.modules.log.utils.ContrastObjUtil;
import com.avic.modules.system.domain.User;
import com.avic.modules.system.service.mapper.SysUserMapper;
import com.avic.utils.FileUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.pagehelper.PageInfo;
import lombok.AllArgsConstructor;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.sql.Timestamp;
import java.util.*;

/**
 * @author zhangzikang 设备维修表
 * @date 2022-08-14
 */
@Service(value = "equipmentRepairService")
@AllArgsConstructor
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
public class EquipmentRepairServiceImpl extends BaseServiceImpl
        <EquipmentRepairMapper, EquipmentRepair> implements EquipmentRepairService {

    private final IGenerator generator;
    private final EquipmentRepairMapper repairMapper;
    private final SysUserMapper userMapper;
    private final EquipmentMapper equipmentMapper;
    private final LogsService logsService;

    public Map<String, Object> queryAll(EquipmentRepairQueryCriteria criteria, Pageable pageable) {
        try {
            if(criteria.getEquipNumber()!=null){
                QueryWrapper<Equipment> wrapper = new QueryWrapper<>();
                wrapper.eq("id", criteria.getEquipNumber());
                Equipment equipment = equipmentMapper.selectOne(wrapper);
                Set<String> all = new HashSet<>();
                if(equipment!=null){
                    QueryWrapper<Equipment> wrapper2 = new QueryWrapper<>();
                    wrapper2.eq("equip_son", equipment.getId());
                    List<Equipment> equipment2 = equipmentMapper.selectList(wrapper2);
                    for(Equipment equip:equipment2){
                        all.add(equip.getId());
                    }
                    all.add(equipment.getId());
                }

                criteria.setEquipNumber1(all);
            }
            if(criteria.getAggregate()!=null && criteria.getAggregate()!=""){
                List<Accept> parse = JSONArray.parseArray(criteria.getAggregate(),Accept.class);
                // 包含id
                Set<String> idAll = new HashSet<>();
                QueryWrapper<EquipmentRepair> wrapper = new QueryWrapper<>();
                for(Accept accept:parse){
                    if(accept.getName().equals("workOrder")){
                        if(accept.getCondition().equals("1")){
                            wrapper.notLike("work_order",accept.getValue());
                        }else if(accept.getCondition().equals("0")){
                            wrapper.like("work_order",accept.getValue());
                        }
                    }else if(accept.getName().equals("equipName")){
                        if(accept.getCondition().equals("1")){
                            wrapper.notLike("equip_name",accept.getValue());
                        }else if(accept.getCondition().equals("0")){
                            wrapper.like("equip_name",accept.getValue());
                        }
                    }else if(accept.getName().equals("reason")){
                        if(accept.getCondition().equals("1")){
                            wrapper.notLike("reason",accept.getValue());
                        }else if(accept.getCondition().equals("0")){
                            wrapper.like("reason",accept.getValue());
                        }
                    }else if(accept.getName().equals("repairResult")){
                        if(accept.getCondition().equals("1")){
                            wrapper.notLike("repair_result",accept.getValue());
                        }else if(accept.getCondition().equals("0")){
                            wrapper.like("repair_result",accept.getValue());
                        }
                    }else if(accept.getName().equals("duration")){
                        if(accept.getCondition().equals("0")){ // 大于
                            wrapper.gt("duration",accept.getValue());
                        }else if(accept.getCondition().equals("1")){ // 小于
                            wrapper.lt("duration",accept.getValue());
                        } else if(accept.getCondition().equals("2")){ // 等于
                            wrapper.eq("duration",accept.getValue());
                        }
                    }else if(accept.getName().equals("repairName")) {
                        if (accept.getCondition().equals("1")) {
                            wrapper.notLike("repair_name", accept.getValue());
                        } else if (accept.getCondition().equals("0")) {
                            wrapper.like("repair_name", accept.getValue());
                        }
                    }else if(accept.getName().equals("completeTime")){
                        if (accept.getCondition().equals("2")){
                            String value = accept.getValue();
                            String[] split = value.split(",", 0);
                            String start = null;
                            String end = null;
                            int sum = 0;
                            for(String spl:split){
                                if(sum==1){
                                    end = spl;
                                } else {
                                    start = spl;
                                }
                                sum ++;
                            }
                            wrapper.between("complete_time", start, end);
                        } else if(accept.getCondition().equals("1")) {
                            wrapper.notBetween("complete_time",accept.getValue()+" 00:00:00",accept.getValue()+" 23:59:59").or().isNull("complete_time");
                        } else if(accept.getCondition().equals("0")) {
                            wrapper.between("complete_time",accept.getValue()+" 00:00:00",accept.getValue()+" 23:59:59");
                        }
                    }
                }
                List<EquipmentRepair> equipmentMaintains = repairMapper.selectList(wrapper);
                for(EquipmentRepair equip:equipmentMaintains){
                    idAll.add(equip.getId());
                }
                if(equipmentMaintains.size()==0){
                    idAll.add("没有东西");
                }
                criteria.setIdAll(idAll);
            }
        } catch (JSONException e) {
            throw new BadRequestException("参数格式不匹配");
        }
        String order = "work_order desc";
        getPageSort(pageable,order);
        PageInfo<EquipmentRepair> page = new PageInfo<>(queryAll(criteria));
        List<EquipmentRepairDto> convert = generator.convert(page.getList(), EquipmentRepairDto.class);
        for(EquipmentRepairDto equip:convert){
            if(equip.getPhotograph()!=null && !equip.getPhotograph().equals("")){
                String[] split = equip.getPhotograph().split(",");
                equip.setEquipSum(split.length);
            }else {
                equip.setEquipSum(0);
            }
            Equipment equipment = equipmentMapper.selectById(equip.getEquipNumber());
            if(equipment!=null){
                equip.setEquipCategoryId(equipment.getEquipCategoryId());
                equip.setStackNumber(equipment.getStackNumber());
            }
        }
        Map<String, Object> map = new LinkedHashMap<>(2);
        map.put("content",convert);
        map.put("totalElements", page.getTotal());
        return map;
    }

    @Override
    public List<EquipmentRepair> queryAll(EquipmentRepairQueryCriteria criteria) {
        return baseMapper.selectList(QueryHelpPlus.getPredicate(EquipmentRepair.class,criteria));
    }

    @Override
    public List<EquipmentRepair> queryAlls(EquipmentRepairQueryCriteria criteria, Pageable pageable) {
        if(criteria.getEquipNumber()!=null){
            QueryWrapper<Equipment> wrapper = new QueryWrapper<>();
            wrapper.eq("id", criteria.getEquipNumber());
            Equipment equipment = equipmentMapper.selectOne(wrapper);
            Set<String> all = new HashSet<>();
            if(equipment!=null){
                QueryWrapper<Equipment> wrapper2 = new QueryWrapper<>();
                wrapper2.eq("equip_son", equipment.getId());
                List<Equipment> equipment2 = equipmentMapper.selectList(wrapper2);
                for(Equipment equip:equipment2){
                    all.add(equip.getId());
                }
                all.add(equipment.getId());
            }

            criteria.setEquipNumber1(all);
        }
        if(criteria.getAggregate()!=null && criteria.getAggregate()!=""){
            List<Accept> parse = JSONArray.parseArray(criteria.getAggregate(),Accept.class);
            // 包含id
            Set<String> idAll = new HashSet<>();
            QueryWrapper<EquipmentRepair> wrapper = new QueryWrapper<>();
            for(Accept accept:parse){
                if(accept.getName().equals("workOrder")){
                    if(accept.getCondition().equals("1")){
                        wrapper.notLike("work_order",accept.getValue());
                    }else if(accept.getCondition().equals("0")){
                        wrapper.like("work_order",accept.getValue());
                    }
                }else if(accept.getName().equals("equipName")){
                    if(accept.getCondition().equals("1")){
                        wrapper.notLike("equip_name",accept.getValue());
                    }else if(accept.getCondition().equals("0")){
                        wrapper.like("equip_name",accept.getValue());
                    }
                }else if(accept.getName().equals("reason")){
                    if(accept.getCondition().equals("1")){
                        wrapper.notLike("reason",accept.getValue());
                    }else if(accept.getCondition().equals("0")){
                        wrapper.like("reason",accept.getValue());
                    }
                }else if(accept.getName().equals("repairResult")){
                    if(accept.getCondition().equals("1")){
                        wrapper.notLike("repair_result",accept.getValue());
                    }else if(accept.getCondition().equals("0")){
                        wrapper.like("repair_result",accept.getValue());
                    }
                }else if(accept.getName().equals("duration")){
                    if(accept.getCondition().equals("0")){ // 大于
                        wrapper.gt("duration",accept.getValue());
                    }else if(accept.getCondition().equals("1")){ // 小于
                        wrapper.lt("duration",accept.getValue());
                    } else if(accept.getCondition().equals("2")){ // 等于
                        wrapper.eq("duration",accept.getValue());
                    }
                }else if(accept.getName().equals("repairName")) {
                    if (accept.getCondition().equals("1")) {
                        wrapper.notLike("repair_name", accept.getValue());
                    } else if (accept.getCondition().equals("0")) {
                        wrapper.like("repair_name", accept.getValue());
                    }
                }else if(accept.getName().equals("completeTime")){
                    if (accept.getCondition().equals("2")){
                        String value = accept.getValue();
                        String[] split = value.split(",", 0);
                        String start = null;
                        String end = null;
                        int sum = 0;
                        for(String spl:split){
                            if(sum==1){
                                end = spl;
                            } else {
                                start = spl;
                            }
                            sum ++;
                        }
                        wrapper.between("complete_time", start, end);
                    } else if(accept.getCondition().equals("1")) {
                        wrapper.notBetween("complete_time",accept.getValue()+" 00:00:00",accept.getValue()+" 23:59:59").or().isNull("complete_time");
                    } else if(accept.getCondition().equals("0")) {
                        wrapper.between("complete_time",accept.getValue()+" 00:00:00",accept.getValue()+" 23:59:59");
                    }
                }
            }
            List<EquipmentRepair> equipmentMaintains = repairMapper.selectList(wrapper);
            for(EquipmentRepair equip:equipmentMaintains){
                idAll.add(equip.getId());
            }
            if(equipmentMaintains.size()==0){
                idAll.add("没有东西");
            }
            criteria.setIdAll(idAll);
        }
        String order = "work_order desc";
        getPageSize(pageable,order);
        return baseMapper.selectList(QueryHelpPlus.getPredicate(EquipmentRepair.class,criteria));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void download(List<EquipmentRepairDto> all, HttpServletResponse response) throws IOException {
        List<Map<String, Object>> list = new ArrayList<>();
        long sum = 1;
        for (EquipmentRepairDto equip : all) {
            if(equip.getPhotograph()!=null && !equip.getPhotograph().equals("")){
                String[] split = equip.getPhotograph().split(",");
                equip.setEquipSum(split.length);
            }else {
                equip.setEquipSum(0);
            }
            Map<String, Object> map = new LinkedHashMap<>();
            map.put("序号", sum);
            map.put("维护工单", equip.getWorkOrder());
            map.put("设备名称", equip.getEquipName());
            map.put("故障拍照", equip.getEquipSum()+"张");
            map.put("故障原因", equip.getReason());
            map.put("维修人员", equip.getRepairName());
            map.put("维修结果", equip.getRepairResult());
            String s = equip.getCompleteTime().toString();
            String substring = s.substring(0, s.length() - 2);
            map.put("维修完成时间",substring);
            map.put("维修时长", equip.getDuration()+"小时");
            sum ++;
            list.add(map);
        }
        // 创建操作日志信息
        LogVo logVo = new LogVo();
        String name = "[导出]了" + "[设备维修记录信息]";
        logVo.setBehavior(name);
        logVo.setAction(LogEnumeration.LEADING_OUT.getMessage());
        logsService.save(logVo);
        FileUtil.downloadExcel(list, response);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addEquipment(EquipmentRepair equipment) {
        EquipmentRepair workOrder = this.getOne(new LambdaQueryWrapper<EquipmentRepair>()
                .eq(EquipmentRepair::getWorkOrder, equipment.getWorkOrder()));
        if(workOrder!=null){
            throw new BadRequestException("维修工单已存在");
        }
        Equipment equipment1 = equipmentMapper.selectById(equipment.getEquipNumber());
        if(equipment1 == null){
            throw new BadRequestException("所选设备不存在");
        }
        if(equipment1.getEquipSonName().equals("") || equipment1.getEquipSonName()==null){
            equipment.setEquipName(equipment1.getEquipName());
        }else {
            equipment.setEquipName(equipment1.getEquipSonName());
        }

        User user = userMapper.selectById(equipment.getRepairUserId());
        if(user == null){
            throw new BadRequestException("所选人员不存在");
        }
        equipment.setRepairName(user.getNickName());

        // 创建操作日志
        LogVo logVo = new LogVo();
        String name1 = "[添加]了"+ " [" + equipment.getEquipName()+ "] " + "设备维修记录信息";
        logVo.setBehavior(name1);
        logVo.setAction(LogEnumeration.Add_TO.getMessage());
        logsService.save(logVo);

        String replace = UUID.randomUUID().toString().replace("-", "");
        equipment.setId(replace);
        equipment.setCreateUserTime(new Timestamp(System.currentTimeMillis()));
        repairMapper.insert(equipment);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void editEquipment(EquipmentRepair equipment) {
        EquipmentRepair workOrder = this.getOne(new LambdaQueryWrapper<EquipmentRepair>()
                .eq(EquipmentRepair::getWorkOrder, equipment.getWorkOrder()));
        if(workOrder!=null){
            if(!workOrder.getId().equals(equipment.getId())){
                throw new BadRequestException("维修工单已存在");
            }
        }
        Equipment equipment1 = equipmentMapper.selectById(equipment.getEquipNumber());
        if(equipment1 == null){
            throw new BadRequestException("所选设备不存在");
        }

        if(equipment1.getEquipSonName().equals("") || equipment1.getEquipSonName()==null){
            equipment.setEquipName(equipment1.getEquipName());
        }else {
            equipment.setEquipName(equipment1.getEquipSonName());
        }

        User user = userMapper.selectById(equipment.getRepairUserId());
        if(user == null){
            throw new BadRequestException("所选人员不存在");
        }
        equipment.setRepairName(user.getNickName());


        // 修改前
        EquipmentRepair repair = repairMapper.selectById(equipment.getId());
        Equipment equipment2 = equipmentMapper.selectById(repair.getEquipNumber());

        RepairVo front = new RepairVo();
        front.setWorkOrder(repair.getWorkOrder());
        front.setEquipType(equipment2.getEquipName());
        front.setEquipName(repair.getEquipName());
        front.setCompleteTime(repair.getCompleteTime().toString());
        front.setDuration(repair.getDuration().toString());
        front.setReason(repair.getReason());
        front.setRepairName(repair.getRepairName());
        front.setRepairResult(repair.getRepairResult());
        front.setStation(equipment2.getStackNumber());

        // 修改后
        RepairVo after = new RepairVo();
        after.setWorkOrder(equipment.getWorkOrder());
        after.setEquipType(equipment1.getEquipName());
        after.setEquipName(equipment.getEquipName());
        after.setCompleteTime(equipment.getCompleteTime().toString());
        after.setDuration(equipment.getDuration().toString());
        after.setReason(equipment.getReason());
        after.setRepairName(equipment.getRepairName());
        after.setRepairResult(equipment.getRepairResult());
        after.setStation(equipment1.getStackNumber());

        // 创建操作日志
        String s = ContrastObjUtil.comparObj(after,front);
        LogVo logVo = new LogVo();
        String name = "[修改]了"+ " [" + repair.getEquipName() + "] " + "设备维修记录信息 ";
        logVo.setBehavior(name);
        logVo.setInformation(s);
        logVo.setAction(LogEnumeration.MODIFY.getMessage());
        logsService.save(logVo);

        repairMapper.updateById(equipment);
    }
}
